package com.example.registry;

import com.example.service.UserServiceImpl;
import com.example.zkconnect.ZkConnection;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.Stat;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.util.NavigableMap;

/**
 * @Description
 * @Author 26233
 * @Create 2021-11-02 13:30:06
 */

public class ServiceRegistry {

    private ZkConnection zkConnection;
    private String serverHost;
    private int serverPort;

    private String rpcProtocol = "rmi";
    private String serviceBaseRmiUrl;

    private String nodePrefix = "/myservice";

    private int rmiServerPort = 9998;

    public ServiceRegistry(){}
    public ServiceRegistry(ZkConnection zkConnection, String serverHost, int serverPort){
        this.zkConnection = zkConnection;
        this.serverHost = serverHost;
        this.serverPort = serverPort;
        serviceBaseRmiUrl = rpcProtocol + "://" + serverHost + ":" + serverPort + "/";

        try {
            RmiServerConfig rmiServerConfig = new RmiServerConfig("192.168.101.8", serverPort);
            LocateRegistry.createRegistry(rmiServerPort, rmiServerConfig, rmiServerConfig);
            System.out.println("rmi server start...");
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public void registry(Class<? extends Remote> service, String serviceName){
        String rmiUrl = serviceBaseRmiUrl + serviceName;
        String path = nodePrefix + "/" + service.getName();
        try {

            Stat exists = zkConnection.getConnect().exists(nodePrefix, true);
            if (exists != null){
                System.out.println("delete exist path: " + nodePrefix);
                zkConnection.getConnect().delete(nodePrefix, exists.getVersion());
            }else {
                zkConnection.getConnect().create(nodePrefix, "service".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            }

            exists = zkConnection.getConnect().exists(path, true);
            if (exists != null){
                System.out.println("delete exist path: " + path);
                zkConnection.getConnect().delete(path, exists.getVersion());
            }
            zkConnection.getConnect().create(path, rmiUrl.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println("create service node: " + "path=" + path + " ,serviceName=" + serviceName);
            Naming.rebind(serviceName, service.newInstance());
            System.out.println("rmi bind service: " + serviceName);

        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        System.out.println("ServiceRegistry.class.getName() = " + ServiceRegistry.class.getName());
        ServiceRegistry serviceRegistry = new ServiceRegistry(null, "192.168.101.8", 8888);
        serviceRegistry.registry(UserServiceImpl.class, "userService");
    }
}
